/*
 * 项目名称:    wms-server-jeecg
 * 创建人员:    hansen
 * 创建时间:    2023-09-20
 */
package org.jeecg.modules.dock.handler.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.plant.service.IWmsSapWarehouseMapService;
import org.jeecg.modules.business.doc.business.vo.WarehousingStrategyOneParamVO;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTaskMaterial;
import org.jeecg.modules.business.warehouse.entity.vo.WmsInReceiptTaskPage;
import org.jeecg.modules.dock.constant.SystemConstants;
import org.jeecg.modules.dock.entity.dto.request.PurchasingIronStorageRequestData;
import org.jeecg.modules.dock.entity.dto.response.SapBaseResponseDTO;
import org.jeecg.modules.dock.enums.DockDataStatus;
import org.jeecg.modules.dock.enums.ReceiptsEnum;
import org.jeecg.modules.dock.enums.SapInterfaceTypeEnum;
import org.jeecg.modules.dock.handler.AbstractSapDataHandler;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产订单入库(外购铁心业务)接口handler(A834)
 *
 * @author ZHAOJUN
 * @version 1.0.0
 * @date 2024-01-08
 */
@Component
@Slf4j
public class PurchasingIronStorageDataHandler extends AbstractSapDataHandler<PurchasingIronStorageRequestData> {

    @Autowired
    private IBasicMaterialService materialService;
    @Autowired
    private WorkFlowService workFlowService;
    @Autowired
    private SapCommonService sapCommonService;
    @Autowired
    private IWmsSapWarehouseMapService wmsSapWarehouseMapService;

    @Value(value = "${wms.config.personnel.sap:}")
    private String personnelSap;
    private static final String WAREHOUSE_DOCUMENT_IN_CODE = "rkrw_rule";
    private static final String WAREHOUSE_PARAM = "{\"prefix\":\"RKRW\"}";
    private static final String SAP_REQUEST_PERSON = "仓管员";

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized List<? extends SapBaseResponseDTO> doHandle(List<PurchasingIronStorageRequestData> data) {
        List<SapBaseResponseDTO> list = new ArrayList<>(16);
        SapBaseResponseDTO sapBaseResponseDTO = null;
        log.info("生产订单入库(外购铁心业务)主数据:{},共{}条", data, data.size());
        if (CollectionUtil.isNotEmpty(data)) {
            List<String> materialCodes = data.stream().map(t -> t.getMaterialCode()).collect(Collectors.toList());
            sapCommonService.verifyExistenceMaterialCode(materialCodes);

            sapBaseResponseDTO = save(data, ReceiptsEnum.R57);
        }
        list.add(sapBaseResponseDTO);
        return list;
    }

    @Override
    public SapInterfaceTypeEnum type() {
        return SapInterfaceTypeEnum.PURCHASING_IRON_STORAGE;
    }

    public SapBaseResponseDTO save(List<PurchasingIronStorageRequestData> orginlist, ReceiptsEnum receiptsEnum) {
        SapBaseResponseDTO responseDTO = new SapBaseResponseDTO();
        if (CollectionUtil.isNotEmpty(orginlist)) {
            //匹配配置仓库
            List<WmsInReceiptTaskMaterial> inMateriallist = new ArrayList<>();
            Map<String, String> unitIdMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(orginlist)) {
                List<String> materialCodes = orginlist.stream().map(t -> t.getMaterialCode()).distinct().collect(Collectors.toList());
                List<BasicMaterial> basicMaterialList = materialService.list(new LambdaQueryWrapper<BasicMaterial>().in(BasicMaterial::getCode, materialCodes));
                //物料表有脏数据重复物料编码,根据物料编码去重
                basicMaterialList = basicMaterialList.stream().filter(o -> ObjectUtil.isNotNull(o.getCode()))
                        .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(BasicMaterial::getCode))), ArrayList::new));
                if (CollectionUtil.isNotEmpty(basicMaterialList)) {
                    unitIdMap = basicMaterialList.stream().collect(Collectors.toMap(t -> t.getCode(), a -> a.getInventoryUnitId()));
                }
            }
            for (PurchasingIronStorageRequestData dto : orginlist) {
                WmsInReceiptTaskMaterial material = new WmsInReceiptTaskMaterial();
                WarehousingStrategyOneParamVO vo = new WarehousingStrategyOneParamVO();
                // 给入库单物料信息赋值
                material.setOriginalSystemNumber(dto.getSaleOrderNumber());
                material.setOriginalSystemLineNumber(dto.getSaleOrderLineNumber().toString());
                material.setSaleOrderNumber(dto.getSaleOrderNumber());
                material.setSaleOrderLineNumber(dto.getSaleOrderLineNumber().toString());

                material.setBatchCode(dto.getBatchCode());
                if (ObjectUtil.isNotNull(dto.getNumber())) {
                    material.setPlanQuantity(dto.getNumber());
                }
                if (ObjectUtil.isNotEmpty(unitIdMap.get(dto.getMaterialCode()))) {
                    material.setWmsBasicUnitId(unitIdMap.get(dto.getMaterialCode()));
                }
                material.setExtraText(JSON.toJSONString(dto));
                // 根据物料code查询物料信息
                List<BasicMaterial> basicMaterials = materialService.listByCode(dto.getMaterialCode());
                if (CollectionUtil.isNotEmpty(basicMaterials)) {
                    BasicMaterial basicMaterial = basicMaterials.get(0);
                    material.setWmsBasicMaterialId(basicMaterial.getId());
                    vo.setMaterialId(basicMaterial.getId());
                    if (StringUtils.isNotEmpty(basicMaterial.getAssistantUnitId())) {
                        material.setUnitAssistId(basicMaterial.getAssistantUnitId());
                        material.setAssistQuantity(BigDecimal.ONE);
                    }
                }
                material.setProductModel(dto.getProductModel());

                vo.setDocumentType(receiptsEnum.getCode());
                material.setProductNumber(dto.getProductOrderCode());

                material.setOriginalWeight(new BigDecimal(dto.getOriginalWeight()));
                // 根据仓库code查询仓库ID
                String wmsBasicWarehouseId = wmsSapWarehouseMapService.getWmsStroeBySapStore(dto.getStoreLocation(), dto.getFactory());
                material.setWmsBasicWarehouseId(wmsBasicWarehouseId);
                if (wmsBasicWarehouseId == null) {
                    material.setSapLocationFactory(dto.getStoreLocation() + "-" + dto.getStoreLocation());
                    material.setWmsBasicWarehouseId("");
                }
                material.setSapLocation(dto.getStoreLocation());

                inMateriallist.add(material);
            }
            WmsInReceiptTaskPage wmsInReceiptTaskPage = new WmsInReceiptTaskPage();
            wmsInReceiptTaskPage.setDocumentType(receiptsEnum.getCode());
            wmsInReceiptTaskPage.setOwnerType("1");
            wmsInReceiptTaskPage.setOrganization("A04A01");
            wmsInReceiptTaskPage.setSysOrgCode("A04A01");
            wmsInReceiptTaskPage.setOwner("A05");
            wmsInReceiptTaskPage.setDocumentCode(FillRuleUtil.executeRule(WAREHOUSE_DOCUMENT_IN_CODE, JSON.parseObject(WAREHOUSE_PARAM)).toString());
            wmsInReceiptTaskPage.setWmsInReceiptTaskMaterialList(inMateriallist);
            wmsInReceiptTaskPage.setOriginalSystem(SystemConstants.SAP);
            wmsInReceiptTaskPage.setRequestTime(new Date());
            wmsInReceiptTaskPage.setRequestPerson(SAP_REQUEST_PERSON);
            wmsInReceiptTaskPage.setTaskDate(DateUtil.parseDate(DateUtil.now()));
            wmsInReceiptTaskPage.setCreateBy(personnelSap);

            if (CollectionUtil.isNotEmpty(wmsInReceiptTaskPage.getWmsInReceiptTaskMaterialList())) {
                WmsInReceiptTaskMaterial taskMaterial = wmsInReceiptTaskPage.getWmsInReceiptTaskMaterialList().get(0);
                wmsInReceiptTaskPage.setOriginalSystemNumber(taskMaterial.getOriginalSystemNumber());
            }
            BaseFlowDto baseFlowDto = new BaseFlowDto();
            baseFlowDto.setBusinessType(receiptsEnum.getType());
            baseFlowDto.setDocumentType(receiptsEnum.getCode());
            baseFlowDto.setCode(receiptsEnum.getRemark());
            baseFlowDto.setData(wmsInReceiptTaskPage);
            try {
                workFlowService.commit(baseFlowDto);
                responseDTO.setResult(DockDataStatus.SUCCESS.getCode());
                responseDTO.setUuid(orginlist.get(0).getUuid());
                log.info("生产订单入库(外购铁心业务)的入库任务已创建");
            } catch (Exception e) {
                responseDTO.setResult(DockDataStatus.FAILURE.getCode());
                responseDTO.setUuid(orginlist.get(0).getUuid());
                responseDTO.setMessage("创建生产订单入库(外购铁心业务)的入库任务异常");
                log.error("创建生产订单入库(外购铁心业务)的入库任务任务: {}", e.toString());
            }
        }
        responseDTO.setResult(DockDataStatus.SUCCESS.getCode());
        responseDTO.setUuid(orginlist.get(0).getUuid());
        return responseDTO;
    }
}
